﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using NCT.Framework.Database;
using NCT.Framework;
using System.Data;

namespace VISS.API.Users {
    class UserMessageBC : IUserMessage, IUserMessageAdmin {

        #region IUserMessage Members

        public bool InsertConversation(UserMessageEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                //Normalize Data
                item.Title = StringUtils.Normalize(item.Title);
                item.Content = StringUtils.Normalize(item.Content);
                item.Type = EUserMessageType.User;
                item.Status = EUserMessageStatus.UnRead;
                item.SenderDeleted = false;
                item.ReceiverDeleted = false;
                
                item.DateCreated = DateTime.Now;

                // Insert UserMessage to DB
                // the result return must be 2 because the store procedure 
                result = UserMessageDA.InsertConversation(item, connectionName, dbCon, dbTrans) == 2;

                //Add log
                if (result) {
                }

                // Insert UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.InsertConversation({0}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool InsertMessage(UserMessageEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                //Normalize Data
                item.Title = StringUtils.Normalize(item.Title);
                item.Content = StringUtils.Normalize(item.Content);
                item.Type = EUserMessageType.User;
                item.Status = EUserMessageStatus.UnRead;
                item.SenderDeleted = false;
                item.ReceiverDeleted = false;

                item.DateCreated = DateTime.Now;

                // Insert UserMessage to DB
                result = UserMessageDA.InsertMessage(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Insert UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.InsertMessage({0}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool SetRead(string userKey, long conversationID) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserMessageDA.UpdateStatus(userKey, conversationID, EUserMessageStatus.Read, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.SetRead({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    conversationID));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool SenderDeleteMessage(string userKey, long messageID) {
            bool result = true;
            
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update UserMessage to DB
                
                result = UserMessageDA.SenderDeleteMessage(messageID, userKey, connectionName, dbCon, dbTrans) > 0;
                
                //Add log
                if (result) {
                }

                // Insert UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.SenderDeleteMessage({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    messageID));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool ReceiverDeleteMessage(string userKey, long messageID) {
            bool result = true;

            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update UserMessage to DB
                result = UserMessageDA.ReceiverDeleteMessage(messageID, userKey, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Insert UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.ReceiverDeleteMessage({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    messageID));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool DeleteConversation(string userKey, long conversationID) {
            bool result = true;
            
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update UserMessage to DB
                result = UserMessageDA.DeleteConversationByUserKeyAndConversationID(userKey, conversationID, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Insert UserMessage into Cache
                if (result && ConfigInfo.UseCache) {
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.DeleteConversation({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    conversationID));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public UserMessageEnt GetConversation(string userKey, long conversationID) {
            UserMessageEnt result = null;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    result = UserMessageDA.GetConversationByConversationIDAndUserKey(userKey, conversationID, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetConversation({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    conversationID));
            }
            return result;
        }

        public List<UserMessageEnt> GetConversationMessages(string userKey, long conversationID) {
            List<UserMessageEnt> result = new List<UserMessageEnt>();
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    List<UserMessageEnt> tempResult = UserMessageDA.GetConversationMessagesByConversationIDAndUserKey(userKey, conversationID, connectionName, null, null);
                    for (int i = 0; i < tempResult.Count; i++) {
                        if (tempResult[i].SentUserKey == userKey && tempResult[i].SenderDeleted == true) {
                            continue;
                        }
                        if (tempResult[i].ReceivedUserKey == userKey && tempResult[i].ReceiverDeleted == true) {
                            continue;
                        }
                        result.Add(tempResult[i]);
                    }
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetConversationMessages({0}, {1}): \n" + ex.ToString(),
                                    userKey,
                                    conversationID));
            }
            return result;
        }

        public List<UserMessageEnt> GetAllConversationWithPaging(string userKey, int page, int recordPerPage, out int totalRecord) {
            List<UserMessageEnt> result = new List<UserMessageEnt>();
            totalRecord = 0;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    totalRecord = UserMessageDA.CountConversationByUserKey(userKey, connectionName, null, null);
                    if (totalRecord == 0) {
                        return result;
                    }

                    int totalPage = totalRecord / recordPerPage;
                    if (totalRecord % recordPerPage != 0) {
                        totalPage++;
                    }
                    if (page > totalPage) {
                        return result;
                    }

                    long startRow = (page - 1) * recordPerPage + 1;
                    long endRow = startRow + recordPerPage - 1;

                    if (endRow > totalRecord) {
                        endRow = totalRecord;
                    }

                    result = UserMessageDA.GetConversationByUserKeyWithPaging(userKey, startRow, endRow, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetAllConversationWithPaging({0}, {1}, {2}): \n" + ex.ToString(),
                                    userKey,
                                    page,
                                    recordPerPage));
            }
            return result;
        }

        public List<UserMessageEnt> GetUnReadConversationWithPaging(string userKey, int page, int recordPerPage, out int totalRecord) {
            List<UserMessageEnt> result = new List<UserMessageEnt>();
            totalRecord = 0;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    totalRecord = UserMessageDA.CountConversationByUserKeyAndStatus(userKey, EUserMessageStatus.UnRead, connectionName, null, null);
                    if (totalRecord == 0) {
                        return result;
                    }

                    int totalPage = totalRecord / recordPerPage;
                    if (totalRecord % recordPerPage != 0) {
                        totalPage++;
                    }
                    if (page > totalPage) {
                        return result;
                    }

                    long startRow = (page - 1) * recordPerPage + 1;
                    long endRow = startRow + recordPerPage - 1;

                    if (endRow > totalRecord) {
                        endRow = totalRecord;
                    }

                    result = UserMessageDA.GetConversationByUserKeyAndStatusWithPaging(userKey, EUserMessageStatus.UnRead, startRow, endRow, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetUnReadConversationWithPaging({0}, {1}, {2}): \n" + ex.ToString(),
                                    userKey,
                                    page,
                                    recordPerPage));
            }
            return result;
        }

        public int GetUnReadMessagesCount(string userKey) {
            int result = 0;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    result = UserMessageDA.CountConversationByUserKeyAndStatus(userKey, EUserMessageStatus.UnRead, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetUnReadMessagesCount({0}, {1}, {2}): \n" + ex.ToString(),
                                    userKey));
            }
            return result;
        }

        public bool CheckUser1CanSendMessageToUser2(string userKey1, string userKey2) {
            bool result = true;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    int numberOfMesssage = UserMessageDA.CountUnReplyMessagesFromUser1ToUser2(userKey1, userKey2, connectionName, null, null);
                    if (numberOfMesssage >= 3) {
                        result = false;
                    }
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.CheckUser1CanSendMessageToUser2({0}, {1}, {2}): \n" + ex.ToString(),
                                    userKey1,
                                    userKey2));
                result = false;
            }
            return result;
        }

        #endregion

        #region IUserMessageAdmin Members

        public List<UserMessageAdminEnt> GetAllWithPaging(int page, int recordPerPage, out long totalRecord) {
            List<UserMessageAdminEnt> result = new List<UserMessageAdminEnt>();
            totalRecord = 0;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    totalRecord = UserMessageDA.CountAll(connectionName, null, null);
                    if (totalRecord == 0) {
                        return result;
                    }

                    int totalPage = (int)(totalRecord / recordPerPage);
                    if (totalRecord % recordPerPage != 0) {
                        totalPage++;
                    }
                    if (page > totalPage) {
                        return result;
                    }

                    long startRow = (page - 1) * recordPerPage + 1;
                    long endRow = startRow + recordPerPage - 1;

                    if (endRow > totalRecord) {
                        endRow = totalRecord;
                    }

                    result = UserMessageAdminDA.GetAllWithPaging(startRow, endRow, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetAllWithPaging({0}, {1}): \n" + ex.ToString(),
                                    page,
                                    recordPerPage));
            }
            return result;
        }

        public List<UserMessageAdminEnt> GetBySentUserKeyWithPaging(string userKey, int page, int recordPerPage, out int totalRecord) {
            List<UserMessageAdminEnt> result = new List<UserMessageAdminEnt>();
            totalRecord = 0;
            try {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    totalRecord = UserMessageAdminDA.CountBySentUserKey(userKey, connectionName, null, null);
                    if (totalRecord == 0) {
                        return result;
                    }

                    int totalPage = totalRecord / recordPerPage;
                    if (totalRecord % recordPerPage != 0) {
                        totalPage++;
                    }
                    if (page > totalPage) {
                        return result;
                    }

                    long startRow = (page - 1) * recordPerPage + 1;
                    long endRow = startRow + recordPerPage - 1;

                    if (endRow > totalRecord) {
                        endRow = totalRecord;
                    }

                    result = UserMessageAdminDA.GetBySentUserKeyWithPaging(userKey, startRow, endRow, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.GetBySentUserKeyWithPaging({0}, {1}, {2}): \n" + ex.ToString(),
                                    userKey,
                                    page,
                                    recordPerPage));
            }
            return result;
        }

        public long CountAll() {
            long result = 0;
            try
            {
                if (ConfigInfo.UseCache) {

                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    result = UserMessageDA.CountAll(connectionName, null, null);
                }
            }
            catch (System.Exception ex)
            {
                LogUtils.Error(string.Format("VISS.Users.UserMessageBC.CountAll(): \n" + ex.ToString()));
                result = 0;
            }
            return result;
        }

        #endregion
    }
}
